/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG                        *
*Copyright (C) 2006, Tony Sparks                                                     *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "Camera.h"
#include "../game/IEntity.h"

#include <iostream>
#include <math.h>

#include "../kernel.h"

extern Kernel* g_kernel;

#define TIME g_kernel->GetTime()

Camera::Camera(void)
{
    m_view.x = 0;
    m_view.y = 0;

    m_view.width  = 800;
    m_view.height = 600;

    m_position.ZeroOut();
    m_dest.ZeroOut();

    m_velocity.ZeroOut();
    m_screenPos.ZeroOut();
    m_baseVel.Set( 200, 200 );
    m_friction  = 1.0f;

    m_time = 0.0f;
    m_shakeIntensity = 1.0f;
    m_shaking = false;
    m_active = true;
    m_id = -1;

}  

/** Update the camera to another location if needed */
void Camera::Update(float dt)
{
    Vector2f nextPosition;
    if ( !m_pathToFollow.empty() )
    {
        nextPosition = m_pathToFollow.back();
        if ( nextPosition.Equals(m_position, 0.1f) )
        {
            m_pathToFollow.pop_back();
        }
    }
    else
    {
        nextPosition = m_dest;  // will automatically go to the preset followed entity
    }
    //Vector2f pos = (nextPosition - m_position);
    //m_velocity = pos * 0.05;

    //m_position = m_position + m_velocity;

    Vector2f destination( nextPosition- m_position );
    m_velocity.Set( destination );
    m_velocity.Normalize();
    
    Vector2f moveTo( ( m_velocity * m_baseVel ) * m_friction * dt );
    if ( moveTo.Length() > destination.Length() )
    {
        moveTo = destination;
    }
    m_position = m_position + moveTo;

    

    if ( m_time > TIME )
    {
        int vertdir = rand()/10000;
        int hortdir = rand()/10000;

        if ( vertdir >= 2 )
            vertdir = -1;

        if ( hortdir >= 2 )
            hortdir = -1;

        Vector2f shakeVelocity( vertdir, hortdir );
        m_position = (m_position + (shakeVelocity * m_shakeIntensity) * dt);
    } 
}

/**
=========================
Move the camera to a specified location
In 2D, all we have to do is translate it on the x & y axis
=========================
*/
void Camera::LookAt( const Vector2f &pos )
{
    SetPosition( pos );
}

/**
=======================
Move the camera over time to a location,
and center it around that location
=======================
*/
void Camera::MoveTo(const Vector2f &dest)
{
    m_dest.x = abs( float(dest.x - m_screenPos.x) );
    m_dest.y = abs( float(dest.y - m_screenPos.y) );
}


/**
=======================
Shake the camera
=======================
*/
void Camera::Shake( float time, float shakeVel )
{
    // cap off shake
    //if ( shakeVel > 1000 || shakeVel < -1000 )
    //    shakeVel = 1000;

    m_shakeIntensity = shakeVel;
    m_time = TIME + time;
}

Camera::~Camera(void)
{
}
